﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using Data.GameData;
using Data.GameData.GameMap;
using Data.GameData.Interfaces;
using Data.GameData.Utils;
using GameFramework;
using GUIDialogs;
using WeifenLuo.WinFormsUI.Docking;

namespace GUIFramework
{
    public static class Commands
    {
        private static EventListener listener = new EventListener();

        #region Private Methods
        private static void CleanUp()
        {
            CloseAll();

            Game.ActiveGame = null;
            Race.ActiveRace = null;

            GameDataStore.EmptyStore("StarInfo");
        }
        #endregion

        #region Game Commands
        /// <summary>
        /// Open the Game Properties Form
        /// </summary>
        public static void ShowGameProperties()
        {
            GameDetails details = new GameDetails();
            DialogResult closeState = details.ShowDialog();
        }

        /// <summary>
        /// Create a new game, standard checks for existing games, saving, etc.
        /// </summary>
        /// <returns>If the game was successfully created</returns>
        public static bool CreateNewGame()
        {
            // TODO: All the standard bits :)
            if (Game.ActiveGame != null)
            {
                // Check ´sure?´
                if (MessageBox.Show("There is a game in progress, do you want to continue.", "Quit current game", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return false;

                // Check ´save?´
                if (Game.ActiveGame.IsDirty)
                {
                    DialogResult result = MessageBox.Show("Do you want to save the current game before quitting.", "Save current game", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                        Commands.SaveGame();
                    else if( result == DialogResult.Cancel)
                        return false;
                }
            }

            CleanUp();

            GameDetails details = new GameDetails();
            DialogResult closeState = details.ShowDialog();

            if (closeState == DialogResult.OK)
            {
                Game.ActiveGame = new Game(details.GameName);
                return true;
            }

            return false;
        }

        public static void LoadGame()
        {
            if (Game.ActiveGame != null)
            {
                // Check ´sure?´
                if (MessageBox.Show("There is a game in progress, do you want to continue.", "Load game", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return;

                // Check ´save?´
                if (Game.ActiveGame.IsDirty)
                {
                    DialogResult result = MessageBox.Show("Do you want to save the current game before quitting.", "Save current game", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                        Commands.SaveGame();
                    else if (result == DialogResult.Cancel)
                        return;
                }
            }

            GameSelection selectDialog = new GameSelection(true);
            DialogResult closeState = selectDialog.ShowDialog();

            if (closeState == DialogResult.OK)
            {
                CleanUp();
                Game.ActiveGame = selectDialog.SelectedGame;
            }
        }

        public static bool QuitGame()
        {
            // TODO: All the questions, sure? save? etc.
            if (Game.ActiveGame != null)
            {
                // Check ´sure?´
                if (MessageBox.Show("There is a game in progress, do you want to continue.", "Quit current game", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return false;

                // Check ´save?´
                if (Game.ActiveGame.IsDirty)
                {
                    DialogResult result = MessageBox.Show("Do you want to save the current game before quitting.", "Save current game", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                        Commands.SaveGame();
                    else if (result == DialogResult.Cancel)
                        return false;
                }
            }

            CleanUp();
            return true;
        }

        public static void SaveGame()
        {
            Game.ActiveGame.Save();
        }
        #endregion

        #region Race Commands
        public static void ShowActiveRaceDialog()
        {
            ActiveRaceDialog dailog = new ActiveRaceDialog();
            if (dailog.ShowDialog() == DialogResult.OK)
                Race.ActiveRace = dailog.SelectedRace();
        }

        public static void CreateRace()
        {
            RaceDetails raceDetails = new RaceDetails(true);
            DialogResult closedState = raceDetails.ShowDialog();

            if (closedState == DialogResult.OK)
            {
                Race newRace = new Race(raceDetails.RaceName, Guid.Empty);
                newRace.HabIndex = raceDetails.HababilityIndex;
                newRace.PerferedEnviroment = raceDetails.PerferedPlanetType;
                newRace.Colour = raceDetails.RacialColour;

                Race.AddNewRace(newRace);

                Framework.CreateRaceStartingSystem(newRace);

                Race.ActiveRace = newRace;
            }
        }

        /// <summary>
        /// Open the Race Properties Form
        /// </summary>
        public static void ShowRaceProperties()
        {
            RaceDetails details = new RaceDetails(false);
            DialogResult closeState = details.ShowDialog();
        }

        /// <summary>
        /// Open the Race Properties Form for a specific race
        /// </summary>
        /// <param name="race">The race to show</param>
        public static void ShowRaceProperties(Race race)
        {
            RaceDetails details = new RaceDetails(race);
            DialogResult closeState = details.ShowDialog();
        }

        #endregion

        #region Tool Commands
        public static Guid CreateNewStarSystem()
        {
            StarSystem starSys = new StarSystem();
            StarSystemInformation starSysInfo = new StarSystemInformation(starSys.Id, Race.ActiveRace.Id, starSys.MapId, "New Star System");

            StarSystem.Add(starSys);
            GameDataStore.Add("StarInfo", starSysInfo);

            StarSystemDetails ssDetails = new StarSystemDetails(starSysInfo.Id);
            DialogResult result = ssDetails.ShowDialog();

            if (result == DialogResult.OK)
            {
                Commands.OpenView(starSys.MapId, ViewType.vtMAP_STRATEGIC);
                return starSysInfo.Id;
            }
            else
            {
                StarSystem.Remove(starSys);
                GameDataStore.Remove("StarInfo", starSysInfo);
            }

            return Guid.Empty;
        }

        public static void ShowRaceRelationsDialog()
        {
            RaceRelations dialog = new RaceRelations();
            DialogResult r = dialog.ShowDialog();
        }

        public static void ShowUnitDesignerDialog()
        {
            UnitDesign dialog = new UnitDesign();
            DialogResult r = dialog.ShowDialog();
        }
        #endregion

        public static void NextTurn()
        {
            Framework.ProcessPreGameTurn();
        }

        /// <summary>
        /// Open the Star System Properties Form for a specific system
        /// </summary>
        /// <param name="race">The race to show</param>
        public static void ShowSystemProperties(Guid systemId)
        {
            StarSystemDetails details = new StarSystemDetails(systemId);
            DialogResult closeState = details.ShowDialog();
        }

        #region Main View GUI Commands
        public static void CloseAllWindowsExcept(Guid raceId)
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGameWindow wind = doc as IGameWindow;
                if( wind != null && wind.Owner != raceId)
                    doc.DockHandler.Close();
            }
        }

        public static void ResetPanesFor(Guid raceId)
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGamePanel panel = doc as IGamePanel;
                if (panel != null)
                    panel.UpdatePanel(new BasicEventArgs(raceId, BasicEventType.eRACE, BasicOperationType.eMODIFY));
            }
        }

        public static void OpenView(int mapId, ViewType type)
        {
            DockContent dock = MainForm.TheForm().GuiFactory.BuildView(type);
            dock.TabPageContextMenuStrip = MainForm.TheForm().ViewTabContextMenu;

            IGameWindow nWind = dock as IGameWindow;
            nWind.Id = mapId;

            dock.Show(MainForm.MainDockPanel);
        }

        public static void OpenToolbox(GamePanelType type, DockState state)
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGamePanel panel = doc as IGamePanel;
                if (panel != null && panel.PanelType == type)
                {
                    doc.DockHandler.Activate();
                    return;
                }
            }

            DockContent dock;
            switch (type)
            {
                case GamePanelType.pECONOMY:
                    dock = MainForm.TheForm().GuiFactory.BuildView(ViewType.vtTOOLBOX_ECONOMY);
                    break;
                case GamePanelType.pFLEETLIST:
                    dock = MainForm.TheForm().GuiFactory.BuildView(ViewType.vtTOOLBOX_FLEETLIST);
                    break;
                case GamePanelType.pKNOWNRACES:
                    dock = MainForm.TheForm().GuiFactory.BuildView(ViewType.vtTOOLBOX_KNOWNRACES);
                    break;
                default:
                case GamePanelType.pSYSTEMLIST:
                    dock = MainForm.TheForm().GuiFactory.BuildView(ViewType.vtTOOLBOX_SYSTEMLIST);
                    break;
            }

            dock.Show(MainForm.MainDockPanel, state);
        }

        public static void Close(IGameWindow window)
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGameWindow wind = doc as IGameWindow;
                if (wind != null && wind.Equals(window))
                {
                    doc.DockHandler.Close();
                    break;
                }
            }
        }

        public static void CloseAll()
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGameWindow wind = doc as IGameWindow;
                if (wind != null)
                    doc.DockHandler.Close();
            }
        }

        public static void CloseAllButThis(IGameWindow window)
        {
            foreach (IDockContent doc in MainForm.MainDockPanel.Contents.ToArray())
            {
                IGameWindow wind = doc as IGameWindow;
                if (wind != null && !wind.Equals(window))
                    doc.DockHandler.Close();
            }
        }
        #endregion
    }
}
